type JSTypeMap = {
  string: string;
  number: number;
  boolean: boolean;
  symbol: symbol;
  bigint: bigint;
  undefined: undefined;
  object: object;
  function: Function;
};
type JSType = keyof JSTypeMap;
type ArgsType<T extends JSType[]> = {
  [K in keyof T]: JSTypeMap[T[K]];
};

/**
 * 函数柯里化类型标注
 */
type Curried<A extends any[], R> = A extends []
  ? () => R
  : A extends [infer P]
  ? (x: P) => R
  : A extends [infer P, ...infer Rest]
  ? (x: P) => Curried<Rest, R>
  : never;

/**
 * 声明柯里化函数
 * @param fn 函数
 */
declare function curry<A extends any[], R>(
  fn: (...args: A) => R
): Curried<A, R>;

/**
 * 声明防抖函数
 * @param fn 函数
 * @param delay 延迟时间
 */
declare function debounce<T extends any[]>(
  fn: (...args: T) => any,
  delay: number
): (...args: T) => void;

declare function addImpl<T extends JSType[]>(
  ...args: [...T, (...args: ArgsType<T>) => any]
): any;
